home *** CD-ROM | disk | FTP | other *** search
- Path: engnews1.Eng.Sun.COM!taumet!clamage
- From: gregor@netcom.com (Greg Colvin)
- Newsgroups: comp.std.c++
- Subject: Cleaning auto_ptr copy semantics.
- Date: 26 Jan 1996 15:47:28 GMT
- Organization: Netcom Online Communications Services (408-241-9760 login: guest)
- Approved: clamage@eng.sun.com (comp.std.c++)
- Message-ID: <gregorDLrrun.K2x@netcom.com>
- NNTP-Posting-Host: taumet.eng.sun.com
- Content-Type: text
- Apparently-To: comp-std-c++@uunet.uu.net
- Content-Length: 5863
- X-Lines: 154
- Originator: clamage@taumet
-
- Our working paper's auto_ptr (20.4.5) specifies a non-const copy constructor
- and assignment operator. This specification makes functions that return
- auto_ptr less useful than I intended, due to a language restriction on
- modifying temporaries. Since changing the language specification seems not
- to be an option, a change to auto_ptr is in order.
-
- The smallest change I can see that preserves the semantics of strict
- ownership is to separate the concepts of "holding a pointer" and "owning
- an object", so that more than one auto_ptr can hold a pointer to an object,
- but only one auto_ptr can own the object.
-
- Note that only the held pointer is directly accessible; which auto_ptr
- owns an object is observable only via the side effects of destructor calls.
- Thus providing const arguments to the copy constructor and assignment
- operator and making release() a const function seem to me a reasonable
- case of "logical constness".
-
- Note also that reset() must go, since the idiom p.reset(q.release())
- cannot safely transfer ownership. I would happily remove get() as well,
- since its primary use may turn out to be leaking pointers.
-
- A simple implementation makes the semantics clear:
-
- template<class X> class auto_ptr {
- X* px;
- mutable bool owner;
- public:
- explicit auto_ptr(X* p=0) : px(p), owner(true) {}
- template<class Y>
- auto_ptr(const auto_ptr<Y>& r) : px(r.release()), owner(true) {}
- template<class Y>
- auto_ptr& operator=(const auto_ptr<Y>& r) {
- if (&r != this) {
- if (owner) delete px; else owner = true;
- px = r.release();
- }
- return *this;
- }
- ~auto_ptr() { if (owner) delete px; }
-
- X& operator*() const { return *px; }
- X* operator->() const { return px; }
- X* get() const { return px; }
- X* release() const { owner = false; return px; }
- };
-
- This implementation is slightly bigger (one bool) and slightly slower
- (two extra tests and two and one-half extra assignments across eight
- functions) than the comparable implementation of the WP semantics. On
- some hardware it might make sense to save space at the cost of masking
- off the ownership bit or trapping memory hardware interrupts.
-
- The changed Working Paper text I plan to propose at Scotts Valley is:
-
-
- 20.4.5 Template class auto_ptr [lib.auto.ptr]
-
- Template auto_ptr holds onto a pointer to an object obtained via new
- and deletes that object when it is the owner of that object and it
- itself is destroyed (such as when leaving block scope 6.7).
-
- namespace std {
- template<class X> class auto_ptr {
- public:
- // 20.4.5.1 construct/copy/destroy:
- explicit auto_ptr(X* p=0);
- template<class Y> auto_ptr(const auto_ptr<Y>&); |
- template<class Y> auto_ptr& operator=(const auto_ptr<Y>&); |
- ~auto_ptr();
- // 20.4.5.2 members:
- X& operator*() const;
- X* operator->() const;
- X* get() const; ?
- X* release() const; |
- |
- };
- }
-
- The auto_ptr provides a semantics of strict ownership. After initial |
- construction an auto_ptr owns the object it holds a pointer to. An |
- object may be safely owned by only one auto_ptr, so copying an auto_ptr |
- copies the pointer and transfers ownership to the destination. |
-
-
- 20.4.5.1 auto_ptr constructors [lib.auto.ptr.cons]
-
- explicit auto_ptr(X* p = 0);
-
- Requires:
- p points to an object of type X or a class derived from X for which
- delete p is defined and accessible, or else p is a null pointer.
- Postconditions:
- *this holds the pointer p. |
- *this is the owner of the object **this. |
-
- template<class Y> auto_ptr(const auto_ptr<Y>& a); |
-
- Requires:
- Y is type X or a class derived from X for which delete(Y*) is
- defined and accessible.
- Effects:
- Calls a.release().
- Postconditions:
- *this holds the pointer returned from a.release(). |
- *this is the owner of the object **this. |
-
- template<class Y> auto_ptr<X>& operator=(const auto_ptr<Y>& a); |
-
- Requires:
- Y is type X or a class derived from X for which delete(Y*) is
- defined and accessible.
- Effects:
- If *this is the owner of **this and this != &a then delete &**this. |
- Calls a.release().
- Returns:
- *this.
- Postconditions:
- *this holds the pointer returned from a.release(). |
- *this is the owner of the object **this. |
-
- ~auto_ptr();
-
- Effects:
- If *this is the owner of **this then delete &**this. |
-
-
- 20.4.5.2 auto_ptr members [lib.auto.ptr.members]
-
- X& operator*() const;
-
- Requires:
- get() != 0
- Returns:
- A reference to the object pointed to by the pointer held by *this. |
-
- X* operator->() const;
-
- Returns:
- The pointer held by *this. |
-
- X* get() const; ?
- ?
- Returns: ?
- The pointer held by *this. |?
-
- X* release() const; |
-
- Returns:
- The pointer held by *this. |
- Postcondition:
- *this is not the owner of the object **this. |
-
-
- |
-
- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
- Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
- is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
-
-